﻿using System;

namespace IntraVision.Web
{
    public static class FormatHelper
    {
        /// <summary>
        /// Возвращает строку в формате "dd.MM.yyyy HH:mm" или "dd.MM.yyyy", если часы и минуты равны 0. Если время не задано, то возвращается пустая строка
        /// </summary>
        public static string ToDateString(this DateTime? dt)
        {
            return dt.HasValue ? dt.Value.ToDateString() : "";
        }

        /// <summary>
        /// Возвращает строку в формате "dd.MM.yyyy HH:mm" или "dd.MM.yyyy", если часы и минуты равны 0.
        /// </summary>
        public static string ToDateString(this DateTime dt)
        {
            return dt.ToString((dt.Hour > 0 || dt.Minute > 0) ? "dd.MM.yyyy HH:mm" : "dd.MM.yyyy");
        }

        /// <summary>
        /// Возвращает время в формате 
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToTimeString(this DateTime? dt)
        {
            return dt.HasValue ? dt.Value.ToTimeString() : "";
        }

        /// <summary>
        /// Возвращает время в формате "HH:mm"
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToTimeString(this DateTime dt)
        {
            return dt.ToString("HH:mm");
        }

        /// <summary>
        /// Возвращает время для дальнейшей раскраски в css
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToCssTimeString(this DateTime dt)
        {
            return string.Format("<span class=\"thr\">{0}</span><sup class=\"tmn\">{1}</sup>", dt.ToString("HH"), dt.ToString("mm"));
            /*if (dt.Minute > 0)
                return string.Format("<span class=\"thr\">{0}</span><sup class=\"tmn\">{1}</sup>", dt.ToString("HH"), dt.ToString("mm"));
            else
                return string.Format("<span class=\"thr\">{0}</span>", dt.ToString("HH"));*/
        }

        /// <summary>
        /// Возвращает время для дальнейшей раскраски в css
        /// </summary>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ToCssTimeString(this DateTime? dt)
        {
            return dt.HasValue ? dt.Value.ToCssTimeString() : "";
        }

        //Устанавливает время 
        public static DateTime? ParseTime(this DateTime dt, string time)
        {
            if (string.IsNullOrEmpty(time) || time.IndexOf(':') < 0 || time.IndexOf(':') != time.LastIndexOf(':')) return null;
            string[] tp = time.Split(':');
            int h = 0;
            int m = 0;
            if (tp[0].Length > 1 && tp[0].StartsWith("0")) tp[0] = tp[0][1].ToString();
            if (tp[1].Length > 1 && tp[1].StartsWith("0")) tp[1] = tp[1][1].ToString();
            if (!Int32.TryParse(tp[0], out h) || !Int32.TryParse(tp[1], out m) || h < 0 || h > 24 || m < 0 || m > 59)
                return null;
            //Если кто-то напишет 24:00
            if (h == 24) { h = 23; m = 59; }
            return DateTime.Today.AddHours(h).AddMinutes(m);
        }

        /// <summary>
        /// Возвращает строку, содержащую число с нужным количеством нулей перед ним
        /// </summary>
        /// <param name="val">число</param>
        /// <param name="digits">какая длина должна быть у числа с нулями</param>
        /// <returns></returns>
        public static string AddLeadingZero(this int val, int digits)
        {
            string result = val.ToString();
            while (result.Length < digits)
                result = "0" + result;
            return result;
        }

        public static string AddLeadingZero(this long val, int digits)
        {
            string result = val.ToString();
            while (result.Length < digits)
                result = "0" + result;
            return result;
        }

        /// <summary>
        /// Склоняет слово в зависимости от числа.
        /// Например: 1 апельсин, 2 апельсина, 5 апельсинов.
        /// </summary>
        /// <param name="number">число</param>
        /// <param name="forms">словоформы в формате апельси-н,на,нов</param>
        /// <param name="withNumber">показывать или нет число перед словом</param>
        /// <returns></returns>
        public static string Decline(this int number, string forms, bool withNumber)
        {
            string root = forms.Substring(0, forms.IndexOf("-"));
            string[] ends = forms.Substring(forms.IndexOf("-")+1).Split(',');
            int i;
            int dten = number%10;
            int dhun = number%100;
            if (dten > 4 || dten == 0 || (dten <= 4 && dhun > 10)) i = 2;
            else i = (dten > 1) ? 1 : 0;
            try
            { return (withNumber ? (number + " ") : "") + root + ends[i]; }
            catch 
            { return number.ToString(); }
        }

        public static string Decline(this int number, string forms)
        {
            return Decline(number, forms, true);
        }

        public static string FormatNumber(this decimal? number)
        {
            return number.HasValue ? number.Value.FormatNumber() : "";
        }

        public static string FormatNumber(this decimal number, string format)
        {
            return string.Format(format, number);
        }

        public static string FormatNumber(this decimal number)
        {
            return number.FormatNumber("{0:#,###,###0.##}");
        }

        /// <summary>
        /// Возвращает текущую строку, написанную с большой буквы
        /// </summary>
        /// <param name="str">строка</param>
        /// <returns></returns>
        public static string Capitalize(this string str)
        {
            if (string.IsNullOrEmpty(str)) return str;
            else return char.ToUpper(str[0]) + str.Substring(1);
        }
    }
}
